/*
 * Copyright (c) 2012 swing-on-fire Team
 * 
 * This file is part of Swing-On-Fire (http://code.google.com/p/swing-on-fire), licensed under the terms of the MIT
 * License (MIT).
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.google.code.swingonfire.component;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Transparency;

import javax.swing.JComponent;

import com.google.code.swingonfire.image.DoubleBufferImage;

public class JImage extends JComponent
{

    private static final long serialVersionUID = -184260753787302874L;

    private final DoubleBufferImage doubleBufferImage = new DoubleBufferImage(Transparency.TRANSLUCENT)
    {

        @Override
        protected void paint(Graphics2D g, int width, int height, Image previousImage)
        {
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

            if (isOpaque())
            {
                g.setColor(getBackground());
                g.fillRect(0, 0, width, height);
            }

            Dimension scaledSize = getScaledSize(width, height);
            Image image = JImage.this.getImage();

            if (image != null)
            {
                int imageWidth = image.getWidth(null);
                int imageHeight = image.getHeight(null);
                int x = (width - scaledSize.width) / 2;
                int y = (height - scaledSize.height) / 2;

                g.drawImage(image, x, y, x + scaledSize.width, y + scaledSize.height, 0, 0, imageWidth, imageHeight,
                    null);
            }
        }

    };

    private Image image;

    public JImage()
    {
        super();

        setPreferredSize(new Dimension(128, 128));
    }

    public Image getImage()
    {
        return image;
    }

    public void setImage(Image image)
    {
        if (this.image != image)
        {
            this.image = image;
            doubleBufferImage.dispose();
            repaint();
        }
    }

    public Image getScaledImage(int width, int height)
    {
        if (image == null)
        {
            return null;
        }

        if ((width <= 0) || (height <= 0))
        {
            return null;
        }

        int originalWidth = image.getWidth(null);
        int originalHeight = image.getHeight(null);
        double scale = Math.min((double) width / originalWidth, (double) height / originalHeight);

        int scaledWidth = (int) (originalWidth * scale);
        int scaledHeight = (int) (originalHeight * scale);

        if ((scaledWidth <= 0) || (scaledHeight <= 0))
        {
            return null;
        }

        return image.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);
    }

    protected Dimension getScaledSize(int targetWidth, int targetHeight)
    {
        int scaledWidth = 0;
        int scaledHeight = 0;

        if ((image != null) && (targetWidth > 0) && (targetHeight > 0))
        {
            int imageWidth = image.getWidth(null);
            int imageHeight = image.getHeight(null);
            double scale = Math.min((double) targetWidth / imageWidth, (double) targetHeight / imageHeight);

            scaledWidth = (int) (imageWidth * scale);
            scaledHeight = (int) (imageHeight * scale);
        }

        return new Dimension(scaledWidth, scaledHeight);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        g.drawImage(doubleBufferImage.getImage(this), 0, 0, null);

        super.paintComponent(g);
    }

}
